using FluentMigrator.Runner;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Npgsql;
using PostgresException = Npgsql.PostgresException;

namespace AuthService.Infrastructure.Database;

/// <summary>
/// 数据库迁移运行器
/// 负责执行数据库架构迁移和初始化
/// </summary>
public class MigrationRunner
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<MigrationRunner> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="serviceProvider">服务提供者</param>
    /// <param name="logger">日志记录器</param>
    public MigrationRunner(IServiceProvider serviceProvider, ILogger<MigrationRunner> logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    /// <summary>
    /// 执行数据库迁移的主要方法
    /// 包含数据库初始化和迁移执行的完整流程
    /// </summary>
    /// <returns>是否成功</returns>
    public async Task<bool> MigrateAsync()
    {
        try
        {
            _logger.LogInformation("开始执行数据库迁移...");

            // 创建服务作用域，确保资源正确释放
            using var scope = _serviceProvider.CreateScope();
            var configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();

            // 创建数据库初始化器实例
            // 负责检查数据库连接、创建数据库（如果不存在）、验证权限等
            var dbInitializer = new DatabaseInitializer(configuration,
                scope.ServiceProvider.GetRequiredService<ILogger<DatabaseInitializer>>());

            // 执行数据库初始化
            // 这一步会：
            // 1. 检查是否能连接到目标数据库
            // 2. 如果不能，检查是否能连接到postgres系统数据库
            // 3. 验证用户是否有创建数据库的权限
            // 4. 创建目标数据库（如果不存在）
            var initResult = await dbInitializer.InitializeAsync();
            if (!initResult.Success)
            {
                _logger.LogError("数据库初始化失败: {ErrorMessage}", initResult.ErrorMessage);
                if (!string.IsNullOrEmpty(initResult.SuggestedSolution))
                {
                    _logger.LogInformation("建议解决方案: {Solution}", initResult.SuggestedSolution);
                }
                return false;
            }

            _logger.LogInformation("数据库初始化成功，开始执行迁移...");

            // 获取FluentMigrator的迁移运行器
            // 这是FluentMigrator框架提供的核心接口
            var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();

            // 执行所有待执行的迁移
            // MigrateUp()会：
            // 1. 检查数据库中的VersionInfo表，了解已执行的迁移
            // 2. 找出所有尚未执行的迁移（版本号大于当前数据库版本的迁移）
            // 3. 按版本号顺序执行这些迁移
            // 4. 在VersionInfo表中记录每个成功执行的迁移
            runner.MigrateUp();

            _logger.LogInformation("数据库迁移执行完成");
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据库迁移执行失败");
            return false;
        }
    }



    /// <summary>
    /// 检查数据库连接
    /// </summary>
    /// <returns>连接是否正常</returns>
    public Task<bool> CheckConnectionAsync()
    {
        try
        {
            using var scope = _serviceProvider.CreateScope();
            var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();

            _logger.LogInformation("数据库连接正常");
            return Task.FromResult(true);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据库连接失败");
            return Task.FromResult(false);
        }
    }
}
